/******************************************************************************
 * Copyright 2022 The AIR Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#pragma once

#include <iomanip>
#include <string>

#include <openssl/evp.h>

#include "crypto-wrapper/include/cw/common.hpp"
namespace cw {

class Digest {
 public:
  explicit Digest(const std::string& name);
  explicit Digest(const EVP_MD* md);

  /**
   *
   * @return 是否可用
   */
  operator bool() const {  // NOLINT
    return md_ != nullptr;
  }

  // process functions
  std::string ProcessInputStream(std::istream* is) const;
  std::string ProcessFile(const std::string& filename) const;
  std::string ProcessString(const std::string& str) const;
  std::string ProcessBuffer(const void* buffer, size_t buflen) const;

  // For friendly use
  inline std::string operator()(std::istream* is) const {
    return HexString(ProcessInputStream(is));
  }
  inline std::string operator()(const std::string& filename) const {
    return HexString(ProcessFile(filename));
  }
  inline std::string operator()(const void* buffer, size_t buflen) const {
    return HexString(ProcessBuffer(buffer, buflen));
  }

 private:
  /**
   *
   * @param bio 不论 函数成功与否 此BIO都会被释放
   * @return    结果 为空则为失败
   */
  std::string ProcessBio(BIO* bio) const;
  const EVP_MD* const md_;
};

}  // namespace cw

#include "impl/digest-impl.hpp"
